package org.zxyj.manage.service.impl;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.zxyj.core.entity.Pagination;
import org.zxyj.core.errorno.SystemErrorNo;
import org.zxyj.core.exception.ServiceException;
import org.zxyj.core.utils.Common;
import org.zxyj.core.utils.UUIDUtils;
import org.zxyj.manage.dao.ICoursePaperDao;
import org.zxyj.manage.entity.CoursePaper;
import org.zxyj.manage.entity.CoursePaperCrop;
import org.zxyj.manage.entity.CoursePaperDetail;
import org.zxyj.manage.entity.Examinee;
import org.zxyj.manage.service.ICoursePaperService;
import org.zxyj.system.domain.User;

@Service
public class CoursePaperServiceImpl implements ICoursePaperService{
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private ICoursePaperDao dao;
		
	@Transactional(rollbackFor = Exception.class)
	public void deleteKsbhExists(Map<String, Object> criteria) {
		//查询模板id下考号重复数据
		List<Map<String, Object>> list = queryRepeatStudentForPaper(criteria);
		if(!CollectionUtils.isEmpty(list)){
			for(Map<String, Object> r : list){
				String studentNo = (String) r.get("STUDENT_NO");
				String id = (String) r.get("id");//答卷记录ID
				Map<String, Object> params = new HashMap<String, Object>();
				params.put("id", id);
				params.put("studentNo", studentNo);
				//删除切图题目小项数据
				this.dao.deletePaperCropTmxx(params);
				//删除切图数据
				this.dao.deletePaperCrop(params);
				//删除答卷记录
				this.dao.deletePaperDetail(params);
				//删除答卷汇总分数信息
				//TODO
			}
		}
		
	}
	
	public Pagination findCoursePaperDetailPage(Map<String, Object> criteria, Pagination pagination) {
		logger.debug("listing entities refer to criteria and pagination, param: criteria[{}], pagination[{}]", criteria, pagination);
		if (null == criteria) {
			criteria = new HashMap<String, Object>();
		}
		criteria.put("pagination", pagination);
		if (null == pagination) {
			pagination = new Pagination();
		}
		pagination.setTotal(this.dao.findCoursePaperDetailCount(criteria));
		if(criteria.containsKey("isMap")){
			pagination.setDatas(this.findCoursePaperDetailMapList(criteria));
		}else{
			pagination.setDatas(this.findCoursePaperDetailList(criteria));
		}
		return pagination;
	}

	public List<CoursePaperDetail> findCoursePaperDetailList(Map<String, Object> criteria) {
		List<CoursePaperDetail> list = this.dao.findCoursePaperDetailList(criteria);
		if(!CollectionUtils.isEmpty(list)){
			return list;
		}
		return null;
	}
	
	public List<Map<String, Object>> findCoursePaperDetailMapList(Map<String, Object> criteria) {
		List<Map<String, Object>> list = this.dao.findCoursePaperDetailMapList(criteria);
		if(!CollectionUtils.isEmpty(list)){
			for(Map<String, Object> m : list){
				String filePath = m.get("filePath")+"";
				if(m.get("filePath") !=null && !StringUtils.isEmpty(filePath)){
					int len = filePath.lastIndexOf("/")+1;
					String shortPath = filePath.substring(len, filePath.length());
					m.put("shortPath", shortPath);
				}
			}
			return list;
		}
		return null;
	}
	
	public CoursePaperDetail findCoursePaperDetailEntity(Map<String, Object> criteria) {
		List<CoursePaperDetail> list = this.findCoursePaperDetailList(criteria);
		if(list != null){
			return list.get(0);
		}
		return null;
	}
	
	public Map<String, Object> findCoursePaperDetail(Map<String, Object> criteria){
		List<Map<String, Object>> list = this.findCoursePaperDetailMapList(criteria);
		if(list != null){
			return list.get(0);
		}
		return null;
	}
	
	@Transactional(rollbackFor = Exception.class)
	public void insertCoursePaperCrop(CoursePaperCrop entity) {
		logger.debug("persistenting entity to DB, param: entity[{}]", entity);

		// 参数校验
		if (null == entity) {
			logger.warn("persistenting entity to DB, param entity is null.");
			throw new ServiceException(SystemErrorNo.PARAMETER_IS_NULL);
		}

		User user = (User) Common.findUserSession();
		entity.setCreator(user);
		this.dao.insertCoursePaperCrop(entity);
	}

	@Transactional(rollbackFor = Exception.class)
	public void updatePaperDetailStatus(CoursePaperDetail entity) {
		this.dao.updatePaperDetailStatus(entity);
	}

	@Override
	public List<Map<String, Object>> queryRepeatStudentForPaper(Map<String, Object> criteria) {
		return this.dao.queryRepeatStudentForPaper(criteria);
	}

	public List<Examinee> queryExamineeList(Map<String, Object> criteria){
		return this.dao.queryExamineeList(criteria);
	}

	@SuppressWarnings("unchecked")
	@Transactional(rollbackFor = Exception.class)
	public void updatePaperCheckResult(Map<String, Object> criteria) {
		Map<String,Map<String,Integer>> kmdjDiffAll = (Map<String, Map<String, Integer>>) criteria.get("kmdjDiffAll");
		Map<String,String> sbcgMap = (Map<String, String>) criteria.get("sbcgMap");
        Map<String,CoursePaperDetail> sbsbMap = (Map<String, CoursePaperDetail>) criteria.get("sbsbMap");
        Map<String,String> kmdjQkMap = (Map<String, String>) criteria.get("kmdjQkMap");
        Map<String,String> rotateMap = (Map<String, String>) criteria.get("rotateMap");
        
        CoursePaperDetail entity = null;
        //将校验通过的记录更新其考生编号，偏差坐标，校验标识等信息   sftg:0-未校验 1-已通过 2-未通过 3-缺考
        if(sbcgMap != null && !sbcgMap.isEmpty()){
            for(Entry<String,String> entry : sbcgMap.entrySet()){
                String id = entry.getKey();
                Map<String,Integer> diffMap = kmdjDiffAll.get(id);
                entity = new CoursePaperDetail();
                entity.setId(id);
                entity.setIsPass(1);
                entity.setIsCrop(1);
                entity.setStudentNo(entry.getValue());
                entity.setOffsetX(diffMap.get("p_x"));
                entity.setOffsetY(diffMap.get("p_y"));
                entity.setRotate(rotateMap.get(id));
                this.dao.updatePaperDetail(entity);
            }
        }
        
        
        //更新校验失败的记录信息
        if(sbsbMap != null && !sbsbMap.isEmpty()){
            for(Entry<String,CoursePaperDetail> entry : sbsbMap.entrySet()){
                String id = entry.getKey();
                Map<String,Integer> diffMap1 = kmdjDiffAll.get(id);
                entity = new CoursePaperDetail();
                entity.setId(id);
                entity.setIsPass(2);
                entity.setStudentNo("");
                entity.setOffsetX(diffMap1.get("p_x"));
                entity.setOffsetY(diffMap1.get("p_y"));
                entity.setRotate(rotateMap.get(id));
                this.dao.updatePaperDetail(entity);
            }
        }
        
        //更新缺考的记录信息
        if(kmdjQkMap != null && !kmdjQkMap.isEmpty()){
            for(Entry<String,String> entry : kmdjQkMap.entrySet()){
                String id = entry.getKey();
                entity = new CoursePaperDetail();
                entity.setId(id);
                entity.setIsPass(3);
                entity.setStudentNo(entry.getValue());
                entity.setRotate(rotateMap.get(id));
                this.dao.updatePaperDetail(entity);
            }
        }
	}
	
	@Transactional(rollbackFor = Exception.class)
	public void clearPaper(Map<String, Object> criteria) {
		//清空切图题目小项数据
		this.dao.clearPaperCropTmxx(criteria);
		//清空切图数据
		this.dao.clearPaperCrop(criteria);
		//清空答卷记录
		this.dao.clearPaperDetail(criteria);
		//清空答卷汇总分数信息
		//TODO
	}

	@Transactional(rollbackFor = Exception.class)
	public void deleteCoursePaper(Map<String, Object> criteria) {
		this.dao.deleteCoursePaper(criteria);
	}

	@Transactional(rollbackFor = Exception.class)
	public void insertCoursePaper(CoursePaper entity) {
		logger.debug("persistenting entity to DB, param: entity[{}]", entity);
		// 参数校验
		if (null == entity) {
			logger.warn("persistenting entity to DB, param entity is null.");
			throw new ServiceException(SystemErrorNo.PARAMETER_IS_NULL);
		}

		User user = (User) Common.findUserSession();
		entity.setCreator(user);
		this.dao.insertCoursePaper(entity);
		logger.debug("entity not exist in DB, then save new entity to DB, entity: {}", entity.getId());
	}
	
	@Transactional(rollbackFor = Exception.class)
	public void insertCoursePaperDetail(CoursePaperDetail entity) {
		logger.debug("persistenting entity to DB, param: entity[{}]", entity);
		// 参数校验
		if (null == entity) {
			logger.warn("persistenting entity to DB, param entity is null.");
			throw new ServiceException(SystemErrorNo.PARAMETER_IS_NULL);
		}

		User user = (User) Common.findUserSession();
		entity.setCreator(user);
		this.dao.insertCoursePaperDetail(entity);
		logger.debug("entity not exist in DB, then save new entity to DB, entity: {}", entity.getId());
	}
	
	public void getPaperFile(Map<String, Object> criteria){
		String fileOutPath = (String) criteria.get("fileOutPath");
		String relativePath = (String) criteria.get("relativePath");
		
		File rootDir = new File(fileOutPath);
		// 判断目录或文件是否存在  
        if (rootDir.exists()) {
            String[] fileList =  rootDir.list();
            for (int i = 0; i < fileList.length; i++) {
                String fileName = fileList[i];
                String filePath = relativePath + fileName;//文件路径
                File file = new File(criteria.get("fileDir") + filePath);
                criteria.put("filePath", filePath);
                // 判断是否为文件  
                if (file.isFile()) {  
                    // 为文件时调用取得文件
                	criteria.put("fileName", fileName);
                    this.saveCoursePaperFile(criteria);
                } else {  
                    // 为目录时继续调用递归  
                    this.getDirectoryFile(criteria);
                }  
            }
        }
	}
	
	//递归所有内部文件夹文件
    public void getDirectoryFile(Map<String,Object> criteria) {
    	String filePath = (String) criteria.get("filePath");
        //如果sPath不以文件分隔符结尾，自动添加文件分隔符  
        if (!filePath.endsWith(File.separator)) {  
        	filePath += "/";  
        }
        File dirFile = new File(criteria.get("fileDir") + filePath);  
        //如果dir对应的文件不存在，或者不是一个目录，则退出  
        if (!dirFile.exists() || !dirFile.isDirectory()) {}  
        //遍历文件夹下的所有文件(包括子目录)  
        File[] files = dirFile.listFiles();  
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()) {  
                // 为文件时调用取得文件
                String fileName = files[i].getName();
                criteria.put("filePath", filePath + fileName);
                criteria.put("fileName", fileName);
                this.saveCoursePaperFile(criteria);
            } else {
                //继续遍历子目录
                String fileName = files[i].getName();
                criteria.put("filePath", filePath + fileName);
                this.getDirectoryFile(criteria);  
            }  
        }  
    }
    
    //保存附件上传记录信息
    public void saveCoursePaperFile(Map<String,Object> criteria){
    	String fileName = (String) criteria.get("fileName");
    	Map<Integer,String> mbMap = (Map<Integer, String>) criteria.get("mbMap");
    	
    	//解析文件名称判断文件正反面
    	int index1 = fileName.lastIndexOf(".");
        String name_ = fileName.substring(0,index1);
        int index2 = name_.lastIndexOf("_");
        String str1 = name_.substring(0, index2);//文件名称
        int size = Integer.valueOf(name_.substring(index2+1,name_.length()));//正反面数值
        String fileName_ = "";
        String courseTemplateId = "";
        int zfmType = 0;
        if(size % 2==0){
        	zfmType = 2; //反面
            if(mbMap.get(zfmType) != null){//存在反面
                String pageNo = "_";
                if(size < 10){
                    pageNo += "0" + size;
                }else{
                	pageNo += size;
                }
                fileName_ = str1 + pageNo;
                courseTemplateId = mbMap.get(zfmType);
            }
        }else {
        	zfmType = 1; //正面
        	fileName_ = name_;
            courseTemplateId = mbMap.get(zfmType);
        }
        
        //保存附件上传记录信息
        CoursePaperDetail entity = new CoursePaperDetail();
        entity.setId(UUIDUtils.UUID());
        entity.setOwner(criteria.get("id")+"");
        entity.setFileName(fileName_);
        entity.setFilePath(criteria.get("filePath")+"");
        entity.setZfmType(zfmType);
        entity.setIsPass(0);
        entity.setIsCrop(0);
        entity.setCourseTemplateId(courseTemplateId);
		this.insertCoursePaperDetail(entity);
    }

    @Transactional(rollbackFor = Exception.class)
	public void deleteCoursePaperForRepeat(Map<String, Object> criteria) {
		this.dao.deleteCoursePaperForRepeat(criteria);
	}

	public Pagination findCoursePaperSurplusStudentPage(Map<String, Object> criteria, Pagination pagination) {
		logger.debug("findCoursePaperSurplusStudentPage listing entities refer to criteria and pagination, param: criteria[{}], pagination[{}]", criteria, pagination);
		if (null == criteria) {
			criteria = new HashMap<String, Object>();
		}
		criteria.put("pagination", pagination);
		if (null == pagination) {
			pagination = new Pagination();
		}
		pagination.setTotal(this.dao.findCoursePaperSurplusStudentCount(criteria));
		pagination.setDatas(this.dao.findCoursePaperSurplusStudentList(criteria));
		return pagination;
	}

	public List<Map<String, Object>> querySurplusStudentClass(Map<String, Object> criteria) {
		return this.dao.querySurplusStudentClass(criteria);
	}

	public List<CoursePaperCrop> findCoursePaperCropList(Map<String, Object> criteria) {
		List<CoursePaperCrop> list = this.dao.findCoursePaperCropList(criteria);
		if(!CollectionUtils.isEmpty(list)){
			return list;
		}
		return null;
	}
	
	public CoursePaperCrop findCoursePaperCropEntity(Map<String, Object> criteria){
		List<CoursePaperCrop> list = this.dao.findCoursePaperCropList(criteria);
		if(!CollectionUtils.isEmpty(list)){
			return list.get(0);
		}
		return null;
	}
}
